#!usr/bin/env python

## Copyright 2014 Francesco Bailo

## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.

## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.

## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.

# parseChangeOrgApi.py

# Call it from console passing database filename: python parseChangeOrgApi.py <database> <API key>

import sqlite3
import sys
import os
import json
import requests
import datetime

# Receive the arguments from bash
database = sys.argv[1] + '.sqlite'
api_key = sys.argv[2]


def main(api_key, database):

    # Open database connection
    conn = sqlite3.connect(database)
    conn.text_factory = str
    cursor = conn.cursor()

    petition_url =  "https://www.change.org/p/caro-beppe-grillo-dai-la-fiducia-al-governo-per-cambiare-l-italia-grillodammifiducia"

    base_api_url = "https://api.change.org/v1"
    
    petition_id = requestPetitionId(base_api_url, petition_url, api_key)
    
    petitionJson = requestPetition(base_api_url, petition_id, api_key)
    parsePetition(petition_id, petitionJson, cursor)
    parseTarget(petition_id, petitionJson, cursor)
    
    requestSignatures(base_api_url, petition_id, api_key, cursor)
    requestReasons(base_api_url, petition_id, api_key, cursor)
    conn.commit()
    

def requestPetitionId (base_api_url, petition_url, api_key):

    url = base_api_url + "/petitions/get_id?petition_url=" + petition_url + "&api_key=" + api_key

    response = requests.get(url).json()

    if 'petition_id' in response:
        return str(response['petition_id'])

    else:
        print "Something went wrong: " + response['messages'][0]
        return


def requestPetition (base_api_url, petition_id, api_key):

    url = base_api_url + "/petitions/" + petition_id + "?api_key=" + api_key

    response = requests.get(url).json()

    if 'title' in response:
        return response

    else:
        print "Something went wrong: " + response['messages'][0]
        return
    

def requestSignatures (base_api_url, petition_id, api_key, cursor):

    url = base_api_url + "/petitions/" + petition_id + "/signatures" + "?api_key=" + api_key

    while True:
        response = requests.get(url).json()

        if 'signatures' in response:
            parseSignature(petition_id, response['signatures'], cursor)

            if response['next_page_endpoint']:
                print "Additional signature page"
                url = response.get('next_page_endpoint') + "&api_key=" + api_key
                print url
            else:
                return   
            
        else:
            print "Something went wrong: " + response['messages'][0]
            return

        
def requestReasons (base_api_url, petition_id, api_key, cursor):

    url = base_api_url + "/petitions/" + petition_id + "/reasons" + "?api_key=" + api_key

    while True:
        response = requests.get(url).json()

        if 'reasons' in response:
            parseReason(petition_id, response['reasons'], cursor)

            if response['next_page_endpoint']:
                print "Additional reason page"
                url = response.get('next_page_endpoint') + "&api_key=" + api_key
                print url
            else:
                return   
            
        else:
            print "Something went wrong: " + response['messages'][0]
            return

    
def parsePetition (petition_id, item, cursor):

    petition = {}
    petition['petition_id'] = petition_id
    petition['title'] = item.get('title')
    petition['status'] = item.get('status')
    petition['url'] = item.get('url')
    petition['overview'] = item.get('overview')
    petition['letter_body'] = item.get('letter_body')
    petition['signature_count'] = item.get('signature_count')
    petition['image_url'] = item.get('image_url')
    petition['category'] = item.get('category')
    petition['goal'] = item.get('goal')
    petition['created_at'] = item.get('created_at')
    petition['end_at'] = item.get('end_at')
    petition['creator_name'] = item.get('creator_name')
    petition['creator_url'] = item.get('creator_url')
    petition['organization_name'] = item.get('organization_name')
    petition['organization_url']  = item.get('organization_url')

    enterPetition(petition, cursor)

    return

    
def enterPetition(object, cursor):

    cursor.execute("INSERT OR IGNORE INTO petition (petition_id, title, status, url, overview, letter_body, signature_count, image_url, category, goal, created_at, end_at, creator_name, creator_url, organization_name, organization_url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
    (
    object['petition_id'],
    object['title'],
    object['status'],
    object['url'],
    object['overview'],
    object['letter_body'],
    object['signature_count'],
    object['image_url'],
    object['category'],
    object['goal'],
    object['created_at'],
    object['end_at'],
    object['creator_name'],
    object['creator_url'],
    object['organization_name'],
    object['organization_url'])
    )    

    return


def parseTarget (petition_id, results, cursor):

    for item in results['targets']:

        target = {}
        target['petition_id'] = petition_id
        target['name'] = item.get('name')
        target['title'] = item.get('title')
        target['type'] = item.get('type')
        target['target_area'] = item.get('target_area')

        enterTarget(target, cursor)

    return
    

def enterTarget(object, cursor):

    cursor.execute("INSERT OR IGNORE INTO target (petition_id, name, title, type, target_area) VALUES (?, ?, ?, ?, ?)",
    (
    object['petition_id'],
    object['name'],
    object['title'],
    object['type'],
    object['target_area'])
    )    

    return

def parseSignature (petition_id, results, cursor):

    for item in results:

        signature = {}
        signature['petition_id'] = petition_id
        signature['name'] = item.get('name')
        signature['city'] = item.get('city')
        signature['state_province'] = item.get('')
        signature['country_name'] = item.get('state_province')
        signature['country_code'] = item.get('country_code')
        signature['signed_at'] = item.get('signed_at')

        enterSignature(signature,cursor)

    return


def enterSignature(object,cursor):

    cursor.execute("INSERT OR IGNORE INTO signature (petition_id, name,city, state_province ,country_name, country_code, signed_at) VALUES (?, ?, ?, ?, ?, ?, ?)",
    (
    object['petition_id'],
    object['name'],
    object['city'],
    object['state_province'],
    object['country_name'],
    object['country_code'],
    object['signed_at'])
    )    

    return


def parseReason (petition_id, results, cursor):

    for item in results:
        
        reason = {}
        reason['petition_id'] = petition_id
        reason['created_at'] = item.get('created_at')
        reason['content'] = item.get('content')
        reason['like_count'] = item.get('like_count')
        reason['author_name'] = item.get('author_name')
        reason['author_url'] = item.get('author_url')

        enterReason(reason, cursor)

    return

    
def enterReason(object,cursor):

    cursor.execute("INSERT OR IGNORE INTO reason (petition_id, created_at, content, like_count, author_name, author_url) VALUES (?, ?, ?, ?, ?, ?)",
    (
    object['petition_id'],
    object['created_at'],
    object['content'],
    object['like_count'],
    object['author_name'],
    object['author_url'])
    )    

    return


def parseUser (results, cursor):

    for item in results:

        user = {}
        user['user_id'] = item.get('user_id')
        user['name'] = item.get('name')
        user['location'] = item.get('location')
        user['city'] = item.get('city')
        user['state_province'] = item.get('state_province')
        user['country_name'] = item.get('country_name')
        user['countr_code'] = item.get('countr_code')

        enterUser(user,cursor)

    return
        

def enterUser(object,cursor):

    cursor.execute("INSERT OR IGNORE INTO user (user_id, name, location, city, state_province, country_name, countr_code) VALUES (?, ?, ?, ?, ?, ?, ?)",
    (
    object['user_id'],
    object['name'],
    object['location'],
    object['city'],
    object['state_province'],
    object['country_name'],
    object['countr_code'])
    )    

    return


def parseOrganization (results, cursor):

    for item in results:

        organization = {}
        organization['organization_id'] = item.get('organization_id')
        organization['name'] = item.get('name')
        organization['location'] = item.get('location')
        organization['address'] = item.get('address')
        organization['city'] = item.get('city')
        organization['state_province'] = item.get('state_province')
        organization['postal_code'] = item.get('postal_code')
        organization['country_name'] = item.get('country_name')
        organization['countr_code'] = item.get('countr_code')
        organization['website'] = item.get('website')
        organization['mission'] = item.get('mission')
        organization['organization_url'] = item.get('organization_url')

        enterOrganization(organization, cursor)

    return


def enterOrganization(object,cursor):

    cursor.execute("INSERT OR IGNORE INTO organization (organization_id, name, location, address, city, state_province, postal_code, country_name, countr_code, website, mission, organization_url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
    (
    object['organization_id'],
    object['name'],
    object['location'],
    object['address'],
    object['city'],
    object['state_province'],
    object['postal_code'],
    object['country_name'],
    object['countr_code'],
    object['website'],
    object['mission'],
    object['organization_url'])
    )    

    return

main(api_key, database)
